/* eslint-disable max-lines */
import {
  ShapePathFormulasKeys,
  type Slide,
  type PPTElement,
  type PPTTextElement,
  type PPTShapeElement,
  type PPTImageElement,
} from '@/types/slides'
import defaultImage from '@/assets/image/Default.png'
import { nanoid } from 'nanoid'
import { VIEWPORT_SIZE } from '@/configs/canvas'

const SYSTEM_FIXED_KEY = {
  系统名称: 'systemName',
  系统图片: 'systemImage',
  系统功能介绍: 'systemDesc',
  功能名称: 'funcName',
  功能描述: 'funcDesc',
  功能图片: 'funcImage',
  功能智能描述: 'funcAiDesc',
  功能单价: 'funcPrice',

  系统描述: 'systemRefer',
  系统价值: 'systemValue',
  过渡句: 'sentence',
  智能描述: 'aiValue',
} as const

type FixedKeyType = keyof typeof SYSTEM_FIXED_KEY

interface ISystemElementOptions {
  left: number
  top: number
  width?: number
  height?: number
}

function getSystemFixedKey(
  key:
    | '系统名称'
    | '系统图片'
    | '系统功能介绍'
    | '智能描述'
    | '过渡句'
    | '系统描述'
    | '系统价值',
): string
function getSystemFixedKey(
  key: '功能名称' | '功能描述' | '功能图片' | '功能单价' | '功能智能描述',
  index: number,
): string

function getSystemFixedKey(key: FixedKeyType, index?: number): string {
  return `${SYSTEM_FIXED_KEY[key]}${index ?? ''}`
}

const logoElement = ({ left, top }: ISystemElementOptions): PPTImageElement => {
  const WIDTH = 161
  return {
    type: 'image',
    id: nanoid(10),
    src: '',
    width: WIDTH,
    height: 35,
    left: left - WIDTH / 2 || 824,
    top: top || 13.5,
    fixedRatio: true,
    rotate: 0,
  }
}

const systemImageElement = (
  key: string,
  { left, top, width, height }: ISystemElementOptions,
): PPTImageElement => {
  const WIDTH = width || 303
  return {
    type: 'image',
    id: nanoid(10),
    src: defaultImage,
    replaceSrc: `{{${key}}}`, // 标识
    width: WIDTH,
    height: height || 234,
    left: left || 0,
    top: top || 0,
    fixedRatio: true,
    rotate: 0,
  }
}

const systemTitleElement = (
  key: string,
  { left, top }: ISystemElementOptions,
): PPTTextElement => {
  const WIDTH = 680
  return {
    type: 'text',
    id: nanoid(10),
    left: left - 200 / 2 || 303,
    top: top || 0,
    width: WIDTH,
    height: 80,
    content: `<p style=""><strong><span style="font-size: 28px;">{{${key}}}</span></strong></p>`,
    rotate: 0,
    defaultFontName: 'Microsoft Yahei',
    defaultColor: '#333',
    vertical: false,
  }
}

const systemDescElement = (
  key: string,
  {
    aiValue = '',
    left,
    top,
    width,
    height,
  }: {
    aiValue?: string
    left?: number
    top?: number
    width?: number
    height?: number
  } = {},
): PPTTextElement => {
  const WIDTH = width || 680
  return {
    type: 'text',
    id: nanoid(10),
    left: left ? left - 150 / 2 : 303,
    top: top || 69,
    width: WIDTH,
    height: height || 50,
    content: `<p style=""><strong><span style="font-size: 18px;">{{${key}}}</span></strong></p>`,
    rotate: 0,
    defaultFontName: 'Microsoft Yahei',
    defaultColor: '#333',
    vertical: false,
    aiValue,
  }
}

/**
 * 系统自定义字段元素
 */
const systemFieldsTextElement = (fixedKeyArr: string[]): PPTTextElement => {
  let content = `<ul style="list-style-type: disc; font-size: 14px; color: #333">${fixedKeyArr
    .map((key) => {
      return `<li><p style="">{{${key}}}</p></li>`
    })
    .join('')}</ul>`

  if (!fixedKeyArr.length) {
    content = ''
  }
  return {
    type: 'text',
    id: nanoid(10),
    left: 320,
    top: 210,
    width: 680,
    height: 156,
    rotate: 0,
    defaultFontName: 'Microsoft Yahei',
    defaultColor: '#333',
    vertical: false,
    content: content,
  }
}

/**
 * 系统方法列表元素
 */
const systemFuncListElement = (
  funcNum: number,
  replaceMap: Map<string, string>,
): PPTElement[] => {
  const elements: PPTElement[] = []

  const COLUMN = 3 // 列数
  const RESIDUE_WIDTH = VIEWPORT_SIZE // 剩余可用宽度

  // 方法整体元素的基准位置
  const baseTop = 320
  const baseLeft = 50

  const verticalSpacing = 120 // 每组之间的垂直间隔
  const horizontalSpacing = RESIDUE_WIDTH / COLUMN // 每组之间的水平间隔

  for (let i = 0; i < funcNum; i++) {
    // 以下元素作为一个组
    const groupId = nanoid(10)

    const topOffset = baseTop + Math.floor(i / COLUMN) * verticalSpacing
    const leftOffset = baseLeft + (i % COLUMN) * horizontalSpacing
    const shape: PPTShapeElement = {
      type: 'shape',
      id: nanoid(10),
      viewBox: [230, 110],
      path: 'M 14 0 L 216 0 Q 231 0 231 14 L 231 98 Q 231 112 216 112 L 14 112 Q 0 112 0 98 L 0 14 Q 0 0 14 0 Z',

      fill: '#ffffff',
      fixedRatio: false,
      rotate: 0,
      pathFormula: ShapePathFormulasKeys.ROUND_RECT,
      keypoints: [0.125],
      opacity: 0.7,
      outline: { width: 2, color: '#525252', style: 'solid' },
      width: 230,
      height: 110,
      groupId,
      left: leftOffset - 5,
      top: topOffset - 5,
    }

    const image: PPTImageElement = {
      type: 'image',
      id: nanoid(10),
      fixedRatio: true,
      rotate: 0,
      width: 90,
      height: 90,
      groupId,
      src: `{{${getSystemFixedKey('功能图片', i)}}}`,
      left: leftOffset,
      top: topOffset,
    }

    const name: PPTTextElement = {
      type: 'text',
      id: nanoid(10),
      width: 146.2917418155982,
      height: 50,
      content: `<p style=""><strong><span style="font-size: 16px;">{{${getSystemFixedKey(
        '功能名称',
        i,
      )}}}</span></strong></p>`,
      rotate: 0,
      defaultFontName: 'Microsoft Yahei',
      defaultColor: '#333',
      vertical: false,
      groupId,
      left: leftOffset + 84,
      top: topOffset - 10,
    }

    const desc: PPTTextElement = {
      type: 'text',
      id: nanoid(10),
      width: 146,
      height: 80,
      content: `<p><span style="font-size: 14px;">{{${getSystemFixedKey('功能描述', i)}}}</span></p>`,
      rotate: 0,
      defaultFontName: 'Microsoft Yahei',
      defaultColor: '#333',
      vertical: false,
      lineHeight: 1,
      paragraphSpace: 5,
      groupId,
      left: leftOffset + 84,
      top: topOffset + 15,
      aiValue: replaceMap ? replaceMap.get(`funcAiDesc${i}`) : '',
    }
    elements.push(shape, name, desc, image)
  }
  return elements
}

/**
 * 系统表头
 */
const systemHeader = (): PPTElement[] => [
  {
    type: 'text',
    id: nanoid(10),
    left: 15,
    top: -8.881784197001252e-16,
    width: 201.8367140982945,
    height: 62,
    content:
      '<p style=""><strong><span style="font-size: 28px;">子系统介绍</span></strong></p>',
    rotate: 0,
    defaultFontName: 'Microsoft Yahei',
    defaultColor: '#333',
    vertical: false,
  },
  {
    type: 'image',
    id: nanoid(10),
    src: '',
    width: 161,
    height: 35,
    left: 824,
    top: 13.5,
    fixedRatio: true,
    rotate: 0,
  },
  {
    type: 'line',
    id: nanoid(10),
    left: 24.674538298516488,
    top: 62,
    start: [0, 0],
    end: [956.7060248259158, 0],
    points: ['', ''],
    color: '#5b9bd5',
    style: 'solid',
    width: 2,
  },
]

/**
 * 生成系统默认布局
 */
const genDefaultSystemLayout = (
  fixedKeyArr: string[],
  funcNum: number,
  replaceMap: Map<string, string>,
): Slide => {
  const header = systemHeader()
  const image = systemImageElement(getSystemFixedKey('系统图片'), {
    left: 20,
    top: 69,
    width: 200,
    height: 150,
  })
  const title = systemTitleElement(getSystemFixedKey('系统名称'), {
    left: 320,
    top: 63,
  })
  const desc = systemDescElement(getSystemFixedKey('系统功能介绍'), {
    left: 320,
    top: 124,
  })
  const fields = systemFieldsTextElement(fixedKeyArr)
  const funcList = systemFuncListElement(Math.min(funcNum, 6), replaceMap)

  const page: Slide = {
    id: nanoid(10),
    elements: [...header, image, title, desc, fields, ...funcList],
    background: {
      type: 'solid',
      color: '#ffffff',
    },
  }

  return page
}

export {
  SYSTEM_FIXED_KEY,
  getSystemFixedKey,
  genDefaultSystemLayout,
  systemImageElement,
  systemTitleElement,
  systemDescElement,
  systemFieldsTextElement,
  systemFuncListElement,
  systemHeader,
  logoElement,
}
